/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package drivemachine;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.WString;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.DosFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 *
 * @author positron
 */
public class Util {

	private interface Kernel32 extends Library {
		public int GetFileAttributesW(WString fileName);
	}

	private static Kernel32 lib = null;

	private static int getWin32FileAttributes(String f) throws IOException {
		if (lib == null) {
			synchronized (Kernel32.class) {
				lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
			}
		}
		return lib.GetFileAttributesW(new WString(f));
	}

	public static boolean isWin32JunctionOrSymlink(String f) throws IOException {
		int attributes = getWin32FileAttributes(f);
		if (attributes == -1) {
			return false;
		}
		return ((0x400 & attributes) != 0);
	}

	public static boolean isLink(Path path, BasicFileAttributes attrs)  {
		if(attrs.isSymbolicLink() || attrs.isOther()) return true;
		if( attrs instanceof DosFileAttributes) {
			try {
				if(Util.isWin32JunctionOrSymlink(path.toFile().getAbsolutePath())) return true;
			} catch (IOException ex) {
				return false;
			}
		}
		return false;
	}

	private static List<String> mounts;
	public static List<String> listMountpoints() {
		if(mounts == null) readMountpoints();
		return mounts;
	}

	private static void readMountpoints() {
		ArrayList<String> t = new ArrayList<>();
		Class unixClass = null;
		Class winClass = null;
		try { unixClass = Class.forName("sun.nio.fs.UnixFileStore"); } catch(Exception e) {};
		try { winClass = Class.forName("sun.nio.fs.WindowsFileStore"); } catch(Exception e) {};
		try {
			FileSystem fs = FileSystems.getDefault();
            for (FileStore store: fs.getFileStores()) {
				String v = null;
				if(winClass != null && winClass.isInstance(store)) {
					try {
						Field field = winClass.getDeclaredField("root");
						field.setAccessible(true);
						v = (String)field.get(store) ;
					} catch (NoSuchFieldException e) {
						throw new IllegalStateException("file field not found", e);
					}
				} else
				if(unixClass != null && unixClass.isInstance(store)) {
					try {
						Field field = unixClass.getDeclaredField("file");
						field.setAccessible(true);
						v = ((Path)field.get(store)).toString();
					} catch (NoSuchFieldException e) {
						throw new IllegalStateException("file field not found", e);
					}
				}
				if(v!=null && !t.contains(v) ) t.add(v);
                
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		Collections.sort(t);
		mounts = t;
	}

}
